package com.shrcl.engineerprocess.domain.impl;

import com.google.common.base.Objects;
import com.shrcl.engineerprocess.domain.CorpWeChatUser;
import com.shrcl.engineerprocess.domain.CorpWeChatUserDAO;
import com.shrcl.engineerprocess.domain.Engineer;
import com.shrcl.engineerprocess.domain.EngineerDAO;
import com.shrcl.engineerprocess.domain.EngineerLevel;
import com.shrcl.engineerprocess.domain.events.EngineerEventsManager;
import com.shrcl.engineerprocess.domain.impl.EngineerImpl;
import com.shrct.businessprocess.organization.RCEmployee;
import edu.fudan.mylang.pf.BaseDAOService;
import edu.fudan.mylang.pf.IGenericQuery;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import org.eclipse.xtext.xbase.lib.DoubleExtensions;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.Functions.Function2;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.ObjectExtensions;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service("com.shrcl.engineerprocess.domain.EngineerDAO")
public class EngineerDAOImpl extends BaseDAOService<Engineer> implements EngineerDAO {
  @Autowired
  private EngineerEventsManager eventManager;
  
  @Autowired
  private CorpWeChatUserDAO corpWeChatUserDAO;
  
  public Engineer create(final Procedure1<? super Engineer> updater) {Engineer engineer=EngineerImpl.create(getObjectFactory());
    final Procedure1<Engineer> _function = new Procedure1<Engineer>() {
        public void apply(final Engineer it) {
          updater.apply(it);
          it.checkValid();
          it.start();
          EngineerDAOImpl.this.eventManager.fireCreated(it);
        }
      };
    Engineer _doubleArrow = ObjectExtensions.<Engineer>operator_doubleArrow(engineer, _function);
    final Procedure1<Engineer> _function_1 = new Procedure1<Engineer>() {
        public void apply(final Engineer eng) {
          final Procedure1<CorpWeChatUser> _function = new Procedure1<CorpWeChatUser>() {
              public void apply(final CorpWeChatUser it) {
                it.setEngineer(eng);
              }
            };
          EngineerDAOImpl.this.corpWeChatUserDAO.create(_function);
        }
      };
    Engineer _doubleArrow_1 = ObjectExtensions.<Engineer>operator_doubleArrow(_doubleArrow, _function_1);
    return _doubleArrow_1;
  }
  
  public void delete(final Engineer engineer) {getObjectFactory().delete(engineer);
    
  }
  
  public Engineer asEngineer(final RCEmployee employee) {
    IGenericQuery<Engineer> query=getObjectFactory().createGenericQuery(Engineer.class,"select e from com.shrcl.engineerprocess.domain.impl.EngineerImpl as e   where ((e.employee) = (:employee)) and  e.active = 1      ").setParameter("employee",employee);
    Engineer _uniqueResult = query.uniqueResult();
    return _uniqueResult;
  }
  
  public Collection<Engineer> getAllLevelEngineers(final EngineerLevel engineerLevel) {IGenericQuery<Engineer> query=getObjectFactory().createGenericQuery(Engineer.class,"select e from com.shrcl.engineerprocess.domain.impl.EngineerImpl as e   where  e.active = 1      ");
    Collection<Engineer> _list = query.list();
    final Function1<Engineer,Boolean> _function = new Function1<Engineer,Boolean>() {
        public Boolean apply(final Engineer it) {
          Boolean _isEngineerLevel = it.isEngineerLevel(engineerLevel);
          return _isEngineerLevel;
        }
      };
    Iterable<Engineer> _filter = IterableExtensions.<Engineer>filter(_list, _function);
    List<Engineer> _list_1 = IterableExtensions.<Engineer>toList(_filter);
    return _list_1;
  }
  
  public Double getAvgEngineerLevelCost(final EngineerLevel engineerLevel, final Date mon) {
    double _xblockexpression = (double) 0;
    {
      Collection<Engineer> _allLevelEngineers = this.getAllLevelEngineers(engineerLevel);
      final Function1<Engineer,Double> _function = new Function1<Engineer,Double>() {
          public Double apply(final Engineer it) {
            Double _costByMonth = it.getCostByMonth(mon);
            return _costByMonth;
          }
        };
      Iterable<Double> _map = IterableExtensions.<Engineer, Double>map(_allLevelEngineers, _function);
      final Function1<Double,Boolean> _function_1 = new Function1<Double,Boolean>() {
          public Boolean apply(final Double it) {
            boolean _notEquals = (!Objects.equal(it, null));
            return Boolean.valueOf(_notEquals);
          }
        };
      Iterable<Double> _filter = IterableExtensions.<Double>filter(_map, _function_1);
      final List<Double> allcosts = IterableExtensions.<Double>toList(_filter);
      double _xifexpression = (double) 0;
      int _size = allcosts.size();
      boolean _notEquals = (_size != 0);
      if (_notEquals) {
        final Function2<Double,Double,Double> _function_2 = new Function2<Double,Double,Double>() {
            public Double apply(final Double a, final Double b) {
              double _plus = DoubleExtensions.operator_plus(a, b);
              return Double.valueOf(_plus);
            }
          };
        Double _reduce = IterableExtensions.<Double>reduce(allcosts, _function_2);
        int _size_1 = allcosts.size();
        double _divide = ((_reduce).doubleValue() / _size_1);
        _xifexpression = _divide;
      }
      _xblockexpression = (_xifexpression);
    }
    return Double.valueOf(_xblockexpression);
  }
  
  public void asAndInitEngineer(final RCEmployee employee) {
    final Engineer emp = this.asEngineer(employee);
    boolean _equals = Objects.equal(emp, null);
    if (_equals) {
      final Procedure1<Engineer> _function = new Procedure1<Engineer>() {
          public void apply(final Engineer it) {
          }
        };
      Engineer _create = this.create(_function);
      final Procedure1<Engineer> _function_1 = new Procedure1<Engineer>() {
          public void apply(final Engineer it) {
            it.setEmployee(employee);
            String _name = employee.getName();
            it.setName(_name);
            it.setIsRemoved(Boolean.valueOf(false));
          }
        };
      ObjectExtensions.<Engineer>operator_doubleArrow(_create, _function_1);
    } else {
      emp.setIsRemoved(Boolean.valueOf(false));
    }
  }
  
  public void inActiveAllEngineers() {IGenericQuery<Engineer> query=getObjectFactory().createGenericQuery(Engineer.class,"select e from com.shrcl.engineerprocess.domain.impl.EngineerImpl as e   where  e.active = 1      ");
    Collection<Engineer> _list = query.list();
    final Function1<Engineer,Boolean> _function = new Function1<Engineer,Boolean>() {
        public Boolean apply(final Engineer it) {
          RCEmployee _employee = it.getEmployee();
          boolean _notEquals = (!Objects.equal(_employee, null));
          return Boolean.valueOf(_notEquals);
        }
      };
    Iterable<Engineer> _filter = IterableExtensions.<Engineer>filter(_list, _function);
    final Procedure1<Engineer> _function_1 = new Procedure1<Engineer>() {
        public void apply(final Engineer item) {
          item.setIsRemoved(Boolean.valueOf(true));
        }
      };
    IterableExtensions.<Engineer>forEach(_filter, _function_1);
  }
}
